; 子程序设计1
; 某年级参加英语4级考试的有250名学生，试编写一程序完成60-69，70-79，80-89，90-100四个分数段的统计工作，
; 要求用子程序完成对应分数段的人数统计工作。
.MODEL SMALL
.STACK
.DATA
    ; 在定义比较长的数据的时候会因为数据超过行限制而出现statement too complex
    ; 或者line to long的错误提示，可以这样定义:
    SCORE DB 90, 75, 26, 3, 8, 60, 86, 24, 93, 34, 60, 82
          DB 16, 45, 74, 43, 88, 93, 56, 83, 12, 68, 31, 1, 49, 94
          DB 19, 99, 32, 37, 12, 98, 17, 42, 43, 66, 47, 81, 6, 100
          DB 99, 49, 75, 79, 14, 60, 38, 76, 0, 59, 51, 5, 96, 21, 47
          DB 34, 45, 63, 59, 84, 45, 75, 11, 82, 2, 97, 43, 3, 18, 80
          DB 24, 87, 17, 75, 43, 73, 42, 26, 96, 8, 51, 42, 20, 67, 3
          DB 47, 67, 7, 99, 92, 93, 3, 51, 74, 22, 14, 100, 14, 10, 64
          DB 80, 67, 23, 93, 85, 26, 82, 99, 54, 10, 20, 26, 83, 68
          DB 26, 20, 2, 67, 53, 86, 28, 7, 88, 21, 73, 25, 36, 93, 38
          DB 49, 27, 48, 19, 67, 63, 76, 88, 1, 26, 0, 101, 1, 39, 1
          DB 94, 0, 83, 89, 27, 43, 88, 2, 28, 10, 20, 17, 80, 30, 9, 53
          DB 60, 14, 48, 44, 26, 86, 88, 10, 27, 33, 51, 0, 97, 11, 46, 32
          DB 10, 78, 68, 69, 73, 67, 101, 13, 87, 71, 13, 39, 84, 13, 54, 26
          DB 9, 13, 5, 25, 76, 2, 9, 17, 21, 98, 12, 45, 43, 52, 79, 46, 27
          DB 25, 4, 89, 3, 58, 92, 70, 53, 40, 53, 68, 15, 31, 93, 56
          DB 92, 66, 99, 93, 26, 59, 85, 38, 58, 80, 11, 84, 58, 89
          DB 78, 25, 57, 8, 25, 50, 78, 45, 18, 22, 33, 50
    SCORE_FAIL DB 0     ; 虽然题设没让求, 但是姑且还是求一下, 反正这部分数值总归要判断
    SCORE_60 DB 0
    SCORE_70 DB 0
    SCORE_80 DB 0
    SCORE_90 DB 0
.CODE
START:  MOV AX, @DATA
        MOV DS, AX

        LEA BX, SCORE
        MOV CX, 250     ; 250 个数据, 循环 250 次统计结果

ONE:    MOV AL, [BX]    ; 设置入口参数
        CALL SCORE_COUNT
        INC BX          ; 修改指针, 指向下一个数据(由于是字节数据所以只需要 INC 一下就行了)
        LOOP ONE

        MOV AX, 4C00H
        INT 21H

SCORE_COUNT         PROC NEAR
                    PUSH CX     ; 对循环计数器 CX 进行压栈保护
                    PUSH BX     ; 对数据指针进行压栈保护

                    CMP AL, 60
                    JB S_SCORE_FAIL ; AL < 60 则不及格
                    CMP AL, 70
                    JB S_SCORE_60   ; AL ∈ [60, 70)
                    CMP AL, 80
                    JB S_SCORE_70   ; AL ∈ [70, 80)
                    CMP AL, 90
                    JB S_SCORE_80   ; AL ∈ [80, 90)
                    JMP S_SCORE_90  ; AL ∈ [90, 100]

    S_SCORE_FAIL:   INC SCORE_FAIL
                    JMP DONE
    S_SCORE_60:     INC SCORE_60
                    JMP DONE
    S_SCORE_70:     INC SCORE_70
                    JMP DONE
    S_SCORE_80:     INC SCORE_80
                    JMP DONE
    S_SCORE_90:     INC SCORE_90

    DONE:           POP BX      ; 恢复现场, 注意出栈顺序是入栈顺序的逆序
                    POP CX
                    RET
    SCORE_COUNT ENDP

    END START